package com.flute.icrawler.framework.framework;

import java.rmi.RemoteException;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.flute.icrawler.app.processor.AbstractProcessor;
import com.flute.icrawler.app.result.StoreImpFactory;
import com.flute.icrawler.app.service.CrawlService;
import com.flute.icrawler.config.CrawlConfig;
import com.flute.icrawler.framework.autoadjust.ExecutorAdjuster;
import com.flute.icrawler.framework.executor.ExecutorMananger;
import com.flute.icrawler.framework.framework.JobServerController.JobStatus;
import com.flute.tools.timer.IntervalExecutor;

public class JobChildController {
	private ExecutorMananger executorManager;
	private LocalCrawlUrlPool processingPool;
	private ExecutorAdjuster processorAdjuster;
	private IntervalExecutor statusExecutor;
	private int jobChildStatus;
	private CrawlConfig crawlConfig = null;

	private static Logger logger = LoggerFactory
			.getLogger(JobChildController.class);

	/**
	 * 启动一个任务的CHILD控制器
	 * 
	 * @param uniformRemoteCrawlUrlPool
	 *            与server共享的URL池的远程RMI对象
	 * @param crawlConfig
	 *            任务的配置
	 * @throws RemoteException
	 */
	public JobChildController(ICrawlUrlPool uniformRemoteCrawlUrlPool,
			CrawlConfig crawlConfig) throws RemoteException {
		this.crawlConfig = crawlConfig;
		this.processingPool = new LocalCrawlUrlPool(uniformRemoteCrawlUrlPool,
				getProcessorDependency());
		this.executorManager = new ExecutorMananger(crawlConfig, processingPool);
		this.processorAdjuster = new ExecutorAdjuster(processingPool,
				executorManager);
		this.statusExecutor = getStatusExecutor();
		this.statusExecutor.setName("JobChild Status WatchDog");
		this.statusExecutor.setInterval(10000);
		if (1 == crawlConfig.getStartUpdate()) {
			this.statusExecutor.setDaemMode(false);
		} else {
			this.statusExecutor.setDaemMode(true);
		}

		Runtime.getRuntime().addShutdownHook(
				new JobChildControllerShutDownHook());
	}

	private ProcessorDependency getProcessorDependency() {

		ProcessorDependency pd = new ProcessorDependency();

		List<AbstractProcessor> processorList = crawlConfig
				.getProcessorConfig().getAbstractProcessors();

		for (int i = 0; i < processorList.size(); i++) {

			AbstractProcessor processor = processorList.get(i);

			pd.addProcessor(processor);

		}

		return pd;

	}

	public void start() {
		this.executorManager.run();
		this.processorAdjuster.run();
		this.statusExecutor.start();
		CrawlService.getInstance().startDefaultStorageService(true,
				StoreImpFactory.getFileStore());
	}

	private IntervalExecutor getStatusExecutor() {

		return new IntervalExecutor() {
			@Override
			public void execute() {
				boolean finish = processingPool.isDone();
				logger.info("check jobChild finish:" + finish);
				if (finish && 0 == crawlConfig.getStartUpdate()) {
					setStatus(JobStatus.ENDED);
					// 任务结束后需要关闭所有的child上线程
					logger.info("Close all thread in child!");

					// 任务结束后需要关闭所有的child上线程
				}
			}
		};
	}

	private void setStatus(int status) {
		if (jobChildStatus != status) {
			jobChildStatus = status;

			// 如果任务结束则停止所有线程
			if (jobChildStatus == JobStatus.ENDED) {
				stop();
			}
		}
	}

	/**
	 * 停止子节点
	 */
	private void stop() {
		executorManager.setFinished(true);
		processorAdjuster.setFinished(true);
		processingPool.setFinished(true);
		this.statusExecutor.setFinish(true);
		CrawlService.getInstance().closeService();
	}

}

class JobChildControllerShutDownHook extends Thread {

	public JobChildControllerShutDownHook() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		CrawlService.getInstance().closeService();

	}
}
